package cn.apthink.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import cn.apthink.model.MenuPermission;
import cn.apthink.model.VMenu;
import cn.apthink.model.VRole;
import cn.apthink.mybatisplus.entity.MenuEntity;
import cn.apthink.mybatisplus.entity.RoleEntity;
import cn.apthink.mybatisplus.entity.RolePermissionEntity;
import cn.apthink.mybatisplus.entity.UserEntity;
import cn.apthink.mybatisplus.entity.UserRoleEntity;
import cn.apthink.mybatisplus.service.MenuService;
import cn.apthink.mybatisplus.service.PermissionService;
import cn.apthink.mybatisplus.service.RolePermissionService;
import cn.apthink.mybatisplus.service.RoleService;
import cn.apthink.mybatisplus.service.UserRoleService;
import cn.apthink.mybatisplus.service.UserService;
import cn.apthink.utility.ObjectUtil;
import cn.apthink.utility.Util;

@Component
public class AuthService {
	@Inject
	RoleService roleService;
	@Inject
	UserService userService;
	@Inject
	UserRoleService userRoleService;
	@Inject
	MenuService menuService;
	@Inject
	RolePermissionService rolePermissionService;
	@Inject
	PermissionService permissionService;

	public Set<VRole> getRolesByUserUid(String userid) {
		QueryWrapper<UserRoleEntity> q = new QueryWrapper<>();
		q.eq("userid", userid);
		List<UserRoleEntity> urs = userRoleService.list(q);
		List<RoleEntity> rs = roleService.list();
		Set<VRole> roles = new HashSet<>();
		if (!Util.isEmpty(urs) && !Util.isEmpty(rs)) {
			urs.forEach(x -> {
				Optional<RoleEntity> o = rs.stream().filter(y -> {
					return y.getId().equals(x.getRoleid());
				}).findAny();
				if (o.isPresent()) {
					roles.add(ObjectUtil.clone(o.get(), VRole.class));
				}
			});
		}
		return roles;
	}

	public Set<VMenu> getMenusByRoles(Set<VRole> roles) {
		List<RolePermissionEntity> rms = rolePermissionService.list();
		Set<String> ms = new HashSet<>();
		if (!Util.isEmpty(rms) && !Util.isEmpty(roles)) {
			roles.forEach(x -> {
				Set<String> ls = rms.stream().filter(y -> {
					return x.getId().equals(y.getRoleid());
				}).map(RolePermissionEntity::getMenuid).collect(Collectors.toSet());
				if (!Util.isEmpty(ls)) {
					ms.addAll(ls);
				}
			});
		}
		List<MenuEntity> ls = menuService.list();
		Set<VMenu> menus = new HashSet<>();
		if (!Util.isEmpty(ms) && !Util.isEmpty(ls)) {
			ls.stream().filter(x -> {
				return ms.contains(x.getId());
			}).forEach(x -> {
				menus.add(ObjectUtil.clone(x, VMenu.class));
			});
		}
		return menus;
	}

	public Set<String> getPermissionByRoles(Set<VRole> roles) {
		List<RolePermissionEntity> rps = rolePermissionService.list();
		Set<String> ps = new HashSet<>();
		if (!Util.isEmpty(rps) && !Util.isEmpty(roles)) {
			roles.forEach(x -> {
				List<String> ls = rps.stream().filter(y -> {
					return x.getId().equals(y.getRoleid());
				}).map(z -> {
					return z.getMenuid() + "#" + z.getPermissionid();
				}).collect(Collectors.toList());
				if (!Util.isEmpty(ls)) {
					ps.addAll(ls);
				}
			});
		}
		return ps;
	}

	public UserEntity getUserByAccount(String account) {
		QueryWrapper<UserEntity> q = new QueryWrapper<>();
		q.eq("account", account);
		return userService.getOne(q);
	}

	public UserEntity getUserByUid(String uid) {
		return userService.getById(uid);
	}

	public List<RolePermissionEntity> saveRolePermission(String roleid, List<MenuPermission> menupermissions) {
		List<RolePermissionEntity> mpList = new ArrayList<>();
		menupermissions.forEach(x->{
			RolePermissionEntity rp = new RolePermissionEntity();
			ObjectUtil.copy(x, rp);
//			David: 采用MyBatisPlus自动填充功能
//			rp.setCreatetime(DateUtil.today());
			rp.setRoleid(roleid);
			mpList.add(rp);
		});
		rolePermissionService.saveBatch(mpList);
		return mpList;
	}
}
